package com.haohan.cloud.scm.bill.api.feign;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haohan.cloud.scm.api.bill.dto.BillInfoDTO;
import com.haohan.cloud.scm.api.bill.entity.ReceivableBill;
import com.haohan.cloud.scm.api.bill.req.BillInfoFeignReq;
import com.haohan.cloud.scm.api.bill.vo.BillInfoVO;
import com.haohan.cloud.scm.api.crm.vo.app.BillPageVO;
import com.haohan.cloud.scm.bill.core.impl.ReceivableBillCoreServiceImpl;
import com.haohan.cloud.scm.bill.service.ReceivableBillService;
import com.haohan.cloud.scm.common.tools.util.RUtil;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.stream.Collectors;

/**
 * @author dy
 * @date 2019/12/5
 * 应收账单
 */
@RestController
@AllArgsConstructor
@RequestMapping("/api/feign/bill/receivable")
@Api(value = "receivableBill", tags = "receivableBill 内部接口服务")
public class BillReceivableFeignApiCtrl {

    private final ReceivableBillCoreServiceImpl receivableBillCoreService;
    private final ReceivableBillService receivableBillService;

    /**
     * 根据编号查询账单
     *
     * @param billSn
     * @return
     */
    @Inner
    @GetMapping("/fetchOneBySn/{billSn}")
    public R<ReceivableBill> fetchOneBySn(@PathVariable("billSn") String billSn) {
        ReceivableBill bill = receivableBillService.fetchBySn(billSn);
        if (null == bill) {
            return R.failed("查不到对应账单, 账单编号有误");
        }
        return RUtil.success(bill);
    }

    /**
     * 根据订单编号查询 普通账单
     *
     * @param orderSn
     * @return 可为null
     */
    @Inner
    @GetMapping("/fetchNormalByOrder/{orderSn}")
    public R<ReceivableBill> fetchNormalByOrder(@PathVariable("orderSn") String orderSn) {
        return RUtil.success(receivableBillService.fetchNormalByOrder(orderSn));
    }

    /**
     * 分页查询账单列表
     *
     * @param req
     * @return R
     */
    @Inner
    @PostMapping("/findPage")
    public R<Page<BillInfoDTO>> fetchReceivablePage(@RequestBody BillInfoFeignReq req) {
        IPage<ReceivableBill> billPage = receivableBillCoreService.queryBillPage(new Page<>(req.getCurrent(), req.getSize()), req);
        Page<BillInfoDTO> result = new Page<>(billPage.getCurrent(), billPage.getSize(), billPage.getTotal());
        if (billPage.getTotal() > 0) {
            result.setRecords(billPage.getRecords().stream().map(BillInfoDTO::new).collect(Collectors.toList()));
        }
        return RUtil.success(result);
    }


    /**
     * 查询账单详情
     *
     * @param req billSn 或 orderSn
     * @return R
     */
    @Inner
    @PostMapping("/fetchOne")
    public R<BillInfoVO> fetchOneReceivable(@RequestBody BillInfoFeignReq req) {
        if (StrUtil.isAllEmpty(req.getBillSn(), req.getOrderSn())) {
            return R.failed("缺少billSn或orderSn");
        }
        return RUtil.success(receivableBillCoreService.queryBillInfo(req.getBillSn(), req.getOrderSn()));
    }

    /**
     * 创建应收账单
     *
     * @param req 必需: orderSn/billType/advanceAmount
     * @return
     */
    @Inner
    @PostMapping("/createBill")
    @ApiOperation(value = "创建应收账单", notes = "创建账单 (若已存在，advanceAmount不同时修改)")
    public R<BillInfoDTO> createReceivable(@RequestBody BillInfoDTO req) {
        if (StrUtil.isEmpty(req.getOrderSn()) || null == req.getBillType()
                || null == req.getAdvanceAmount() || req.getAdvanceAmount().compareTo(BigDecimal.ZERO) < 0) {
            return R.failed("缺少参数");
        }
        BillInfoDTO bill = receivableBillCoreService.createBill(req);
        if (null == bill) {
            return R.failed("创建应收账单失败");
        }
        return RUtil.success(bill);
    }

    /**
     * 根据订单信息更新账单(普通账单)
     * 无账单时无操作
     * 账单不能已结算
     * @param req  orderSn、billType
     * @return
     */
    @Inner
    @PostMapping("/updateBillByOrder")
    @ApiOperation(value = "根据订单信息更新账单")
    public R<Boolean> updateBillByOrder(@RequestBody BillInfoFeignReq req) {
        return RUtil.success(receivableBillCoreService.updateBillByOrder(req.getOrderSn(), req.getBillType()));
    }

    /**
     * 账单审核通过（创建结算单）
     * 审核不通过 改变状态
     *
     * @param req 必须 billSn、successFlag 可选 remarks
     * @return
     */
    @Inner
    @PostMapping("/review")
    @ApiOperation(value = "账单审核")
    public R<Boolean> receivableReview(@RequestBody BillInfoFeignReq req) {
        return RUtil.success(receivableBillCoreService.reviewBill(req.getBillSn(), req.getSuccessFlag(), req.getRemarks()));
    }

    /**
     * 按下单客户统计 账单金额
     *
     * @param req customerId、reviewStatus、billType、settlementStatus、customerIdSet
     *            excludeStatus、advanceFlag 、startDate、endDate(可单独使用)
     *            current、size
     * @return customerId、customerName、billAmount
     */
    @Inner
    @PostMapping("/countCustomer")
    @ApiOperation(value = "按下单客户统计 账单金额")
    public R<BillPageVO<BillInfoDTO>> countBillByCustomer(@RequestBody BillInfoFeignReq req) {
        return RUtil.success(receivableBillCoreService.countBillByCustomer(new Page<>(req.getCurrent(), req.getSize()), req));
    }

    /**
     * 账单统计 总数量、总金额
     *
     * @param req customerId、reviewStatus、billType、settlementStatus、customerIdSet
     *            excludeStatus、advanceFlag 、startDate、endDate(可单独使用)
     * @return total、billAmount
     */
    @Inner
    @PostMapping("/countBill")
    @ApiOperation(value = "按下单客户统计 账单金额")
    public R<BillInfoDTO> countBill(@RequestBody BillInfoFeignReq req) {
        return RUtil.success(receivableBillCoreService.countBill(req));
    }

    @Inner
    @PostMapping("/createNormalBillBatch")
    @ApiOperation(value = "批量创建普通账单")
    public R<Boolean> createNormalBillBatch(@RequestBody BillInfoFeignReq req) {
        return RUtil.success(receivableBillCoreService.createNormalBillBatch(req.getOrderSnSet(), req.getBillType()));
    }

    @Inner
    @PostMapping("/updateCustomerName")
    @ApiOperation(value = "修改账单中客户名称")
    public R<Boolean> updateCustomerName(@RequestBody BillInfoFeignReq req) {
        return RUtil.success(receivableBillCoreService.updateCustomerName(req.getCustomerId(), req.getCustomerName()));
    }


    @Inner
    @PostMapping("/deleteBillByOrder")
    @ApiOperation(value = "删除账单 不为已审核通过")
    public R<Boolean> deleteBillByOrder(@RequestBody BillInfoFeignReq req) {
        return RUtil.success(receivableBillCoreService.deleteBillByOrder(req.getOrderSn(), req.getBillType()));
    }


}
